﻿using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Fuse8.ContentManagementFramework.Domain;
using Fuse8.ContentManagementFramework.Domain.Commands;
using Fuse8.ContentManagementFramework.SystemFacade;
using Fuse8.DomainFramework.BusinessService;
using Fuse8.DomainFramework.Common.Locator;

namespace Fuse8.ContentManagementFramework.BizFacade.Services
{
    public class CmsEntityMetaFieldLinkService : BaseBusinessService<CmsEntityMetaFieldLink, int>
    {
        protected override void OnCreating(EntityPreEventArgs<CmsEntityMetaFieldLink, int> e)
        {
            base.OnCreating(e);
            if (e.Entity.EntityMetaField.IsNew)
            {
                new BusinessServiceFacade<CmsEntityMetaField, int>().Add(e.Entity.EntityMetaField);
                e.Entity.EntityMetaFieldId = e.Entity.EntityMetaField.Id;
            }

            var allMetas = FindForEntityType(e.Entity.EntityTypeParameter).ToList();
            if (allMetas.Any())
            {
                e.Entity.MetaFieldOrder = allMetas.Max(p => p.MetaFieldOrder) + 1;
            }
            else
            {
                e.Entity.MetaFieldOrder = 1;
            }
        }

        protected override void OnUpdated(EntityEventArgs<CmsEntityMetaFieldLink, int> e)
        {
            base.OnUpdated(e);

            new BusinessServiceFacade<CmsEntityMetaField, int>().Save(e.Entity.EntityMetaField);            
        }

        /// <summary>
        /// Moves CmsEntityMetaFieldLink to one position up
        /// </summary>
        /// <param name="id">Id of moved entity</param>
        /// <returns>Updated moved entity</returns>
        public CmsEntityMetaFieldLink MoveUp(int id)
        {
            return MoveToPosition(id, -1);
        }

        /// <summary>
        /// Moves CmsEntityMetaFieldLink to one position down
        /// </summary>
        /// <param name="id">Id of moved entity</param>
        /// <returns>Updated moved entity</returns>
        public CmsEntityMetaFieldLink MoveDown(int id)
        {
            return MoveToPosition(id, 1);
        }

        /// <summary>
        /// Gets list of meta field links for specified entity type
        /// </summary>
        /// <param name="entityType"></param>
        /// <returns></returns>
        public IEnumerable<CmsEntityMetaFieldLink> FindForEntityType(string entityType)
        {
            var command = DependencyServiceLocator.Current.GetInstance<CmsEntityMetaFieldLinkForTypeCommand>();
            command.EntityType = entityType;
            var cmsEntityMetaFieldLinks = Find(command).ToList();
            if (cmsEntityMetaFieldLinks.Count > 0)
            {
                cmsEntityMetaFieldLinks.First().IsFirst = true;
                cmsEntityMetaFieldLinks.Last().IsLast = true;
            }
            return cmsEntityMetaFieldLinks;
        }

        private CmsEntityMetaFieldLink MoveToPosition(int id, int shift)
        {
            var entity = FindOne(id);
            var allMetas = FindForEntityType(entity.EntityTypeParameter).ToList();
            for (int i = 0; i < allMetas.Count; i++)
            {
                var newIndex = i + shift;
                if ((newIndex >= 0 && newIndex <= allMetas.Count - 1) && allMetas[i].Id == id)
                {
                    int currentOrder = allMetas[i].MetaFieldOrder;
                    allMetas[i].MetaFieldOrder = allMetas[newIndex].MetaFieldOrder;
                    allMetas[newIndex].MetaFieldOrder = currentOrder;
                    Save(allMetas[i]);
                    Save(allMetas[newIndex]);
                    break;
                }
            }

            return entity;
        }

    }
}